package com.project.m.api.busi.handlers.hicatcard.merchant;

import com.alibaba.fastjson.JSON;
import com.project.m.api.busi.bean.merchant.MerchantTransactionPerformReq;
import com.project.m.api.busi.bean.merchant.MerchantTransactionPerformResp;
import com.project.m.api.busi.config.BusiError;
import com.project.m.api.busi.db.entity.hicatcard.card.TCard;
import com.project.m.api.busi.db.entity.hicatcard.merchant.TMerchant;
import com.project.m.api.busi.db.entity.hicatcard.transaction.TTransaction;
import com.project.m.api.busi.db.entity.hicatcard.user.TUserCarLicence;
import com.project.m.api.busi.db.entity.hicatcard.user.TUserCard;
import com.project.m.api.busi.db.service.hicatcard.WxTokenService;
import com.project.m.api.busi.db.service.hicatcard.card.CardService;
import com.project.m.api.busi.db.service.hicatcard.merchant.MerchantService;
import com.project.m.api.busi.db.service.hicatcard.pay.PayOrderService;
import com.project.m.api.busi.db.service.hicatcard.transaction.TransactionService;
import com.project.m.api.busi.db.service.hicatcard.user.UserCarLicenceService;
import com.project.m.api.busi.db.service.hicatcard.user.UserCardService;
import com.project.m.api.busi.db.service.hicatcard.user.UserService;
import com.project.m.api.busi.handlers.MerchantBizParamChecker;
import com.project.m.api.busi.util.IdGenerator.IdGenerator;
import com.project.m.api.busi.util.Base64;
import com.project.m.api.busi.util.CommonConvertor;
import com.project.m.api.busi.util.TimeUtil;
import com.project.m.api.common.biz.BizHandler;
import com.project.m.api.validates.ValidateParam;
import com.project.m.api.validates.ValidateRet;
import com.project.m.api.validates.ValidateType;
import com.project.m.api.validates.ValidateUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;

//https://mp.weixin.qq.com/debug/wxadoc/dev/api/notice.html#模版消息管理

@Component
public class MerchantTransactionPerformBizHandler
        extends MerchantBizParamChecker<MerchantTransactionPerformReq, MerchantTransactionPerformResp>
        implements BizHandler<MerchantTransactionPerformReq, MerchantTransactionPerformResp> {

    private final Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    WxTokenService wxTokenService;

    @Autowired
    PayOrderService payOrderService;

    @Autowired
    UserService userService;

    @Autowired
    MerchantService merchantService;

    @Autowired
    UserCardService userCardService;

    @Autowired
    CardService cardService;

    @Autowired
    UserCarLicenceService userCarLicenceService;

    @Autowired
    TransactionService transactionService;

    @Value("${weixin.miniapp.appid}")
    String wxMinAppId;

    @Value("${weixin.miniapp.secret}")
    String wxMinAppSecret;

    @Value("${weixin.message.send.template.transaction}")
    private String messageTemplate;

    @Override
    public MerchantTransactionPerformResp handle(MerchantTransactionPerformReq bizRequest) throws Exception {
        // TODO Auto-generated method stub
        MerchantTransactionPerformResp bizResp = new MerchantTransactionPerformResp();
        // 参数检查
        ValidateRet vRet = checkParam(bizRequest, bizResp);
        if (!vRet.isValid()) {
            return bizResp;
        }

        try {
            Long merchant_id = Long.parseLong(bizRequest.getMerchant_id());
            bizRequest.setUser_card_number(getUserCardNumber(bizRequest.getUser_card_number()));

            logger.info("bizRequest.getUser_card_number() = " + bizRequest.getUser_card_number());

            // 检查merchant
            TMerchant merchant = merchantService.findByMerchantId(merchant_id, true);
            if (merchant == null) {
                bizResp.setResult_code(BusiError.ERR_CODE_MERCHANT_NOT_EXIST);
                bizResp.setError_message(BusiError.ERR_MSG_MERCHANT_NOT_EXIST);
                return bizResp;
            }

            // 找user_card
            List<TUserCard> userCardList = userCardService
                    .findByUserCardNumberAndEnable(bizRequest.getUser_card_number(), true);
            if (userCardList == null || userCardList.size() == 0) {
                bizResp.setResult_code(BusiError.ERR_CODE_USER_CARD_NOT_EXIST);
                bizResp.setError_message(BusiError.ERR_MSG_USER_CARD_NOT_EXIST);
                return bizResp;
            }

            TUserCard userCard = userCardList.get(0);
            if (!userCard.getStatus().equals(TUserCard.STATUS_ACTIVE)) {
                bizResp.setResult_code(BusiError.ERR_CODE_USER_CARD_NOT_ACTIVATED);
                bizResp.setError_message(BusiError.ERR_MSG_USER_CARD_NOT_ACTIVATED);
                return bizResp;
            }

            TCard card = cardService.findByCardId(userCard.getCardId());
            if (card == null) {
                bizResp.setResult_code(BusiError.ERR_CODE_CARD_NOT_EXIST);
                bizResp.setError_message(BusiError.ERR_MSG_CARD_NOT_EXIST);
                return bizResp;
            }

            //判断是否本商家的卡
            if (card.getType().equalsIgnoreCase(TCard.TYPE_THIRD_PARTY)) {
                String merchantIdString = CommonConvertor.convertStringAvoidNull(card.getMerchantId());
                String[] merchantIdStringList = merchantIdString.split(",");
                boolean isMerchant = false;
                for (int i = 0; i < merchantIdStringList.length; i++) {
                    try {
                        logger.info("merchantIdStringList[i] = " + merchantIdStringList[i]);
                        Long merchantIdCompare = Long.valueOf(merchantIdStringList[i]);
                        if (merchant_id.longValue() == merchantIdCompare.longValue()) {
                            isMerchant = true;
                            break;
                        }
                    } catch (Exception e) {
                    }
                }

                if (!isMerchant) {
                    bizResp.setResult_code(BusiError.ERR_CODE_CARD_MERCHANT_ERROR);
                    bizResp.setError_message(BusiError.ERR_MSG_CARD_MERCHANT_ERROR);
                    return bizResp;
                }
            }


            List<TTransaction> transactionList = transactionService.findByUserId(userCard.getUserId());
            if (!CollectionUtils.isEmpty(transactionList)) {
                TTransaction transaction = transactionList.get(0);

                String timeCompared = TimeUtil.getXSecondLater(TimeUtil.DATE_PATTERN_NOSEPARTOR, -30);
                logger.info("timeCompared = " + timeCompared);
                logger.info("transaction.getCreateTime() = " + transaction.getCreateTime());
                if (transaction.getCreateTime().compareToIgnoreCase(timeCompared) > 0) {
                    bizResp.setResult_code(BusiError.ERR_CODE_MERCHANT_SETTLE_TIME_TOO_SHORT);
                    bizResp.setError_message(BusiError.ERR_MSG_MERCHANT_SETTLE_TIME_TOO_SHORT);
                    return bizResp;
                }
            }


            // 找用户车牌号
            List<TUserCarLicence> userCarLicenceList = userCarLicenceService.findByUserIdAndEnable(userCard.getUserId(),
                    true);

            TTransaction transaction = new TTransaction();
            transaction.setTransactionOrder(
                    IdGenerator.generateOrderId(IdGenerator.ORDERID_PREFIX_TRANSACTION, "00", "0000"));
            transaction.setMerchantId(merchant.getMerchantId());
            transaction.setUserId(userCard.getUserId());
            transaction.setUserCardId(userCard.getUserCardId());
            transaction.setStatus(TTransaction.STATUS_NOT_SETTLE);
            if (userCarLicenceList == null || userCarLicenceList.size() == 0) {
                transaction.setCarLicence("");
            } else {
                transaction.setCarLicence(userCarLicenceList.get(0).getCarLicenceNumber());
            }
            transaction.setCreateTime(TimeUtil.getCurrTime());
            transaction.setUpdateTime(TimeUtil.getCurrTime());
            transaction.setEnable(true);

            logger.info("services = " + JSON.toJSONString(bizRequest.getServices()));

            userCardService.saveCardTransaction(userCard, transaction, bizRequest.getServices());

            bizResp.setResult_code(BusiError.ERR_CODE_SUCCESS);
            bizResp.setError_message("");
            bizResp.setTransaction_order(transaction.getTransactionOrder());
            return bizResp;

        } catch (Exception e) {
            logger.error("MerchantCardQueryBizHandler", e);
            bizResp.setResult_code(BusiError.ERR_CODE_DB_SAVE);
            bizResp.setError_message(BusiError.ERR_MSG_DB_SAVE);
            return bizResp;
        }
    }

    public String getUserCardNumber(String userCardNumber) {
        try {
            if (userCardNumber.length() > 32) {
                logger.info("after base 64 = " + Base64.decode(userCardNumber, "UTF-8"));
                return Base64.decode(userCardNumber, "UTF-8").substring(0, 32);
            } else {
                return userCardNumber;
            }
        } catch (Exception e) {
            return userCardNumber;
        }
    }

    @Override
    public ValidateRet checkParam(MerchantTransactionPerformReq req, MerchantTransactionPerformResp resp) {
        ValidateRet vRet = super.checkParam(req, resp);
        if (!vRet.isValid())
            return vRet;
        List<ValidateParam> paramList = new ArrayList<ValidateParam>();
        paramList.add(new ValidateParam("merchant_id", ValidateType.NOTBLANK, req.getMerchant_id()));
        paramList.add(new ValidateParam("user_card_number", ValidateType.NOTBLANK, req.getUser_card_number()));

        vRet = ValidateUtil.validate(paramList);
        if (vRet == null) {
            vRet = new ValidateRet(true, "");
        }

        if (!vRet.isValid()) {
            resp.setResult_code(BusiError.ERR_CODE_PARAM_BAD_REQ);
            resp.setError_message(vRet.getErrMsg());
        }

        return vRet;
    }
}
